######################################################################## # # Ots Hardware Mapping Language (OHML) Source File # # Hardware : Hercules DJ Console MK1 DJ MIDI Hardware Controller # File Name : (Ots) Hercules DJ Console MK1 (Channel 1).ohm # Last Updated : 27-November-2009 # OtsAV Version : 1.85.64, 1.85.73 # # Copyright 1996-2008 Ots Corporation # # SPECIAL NOTE: Use this file if your controller has the firmware which # is based on MIDI Channel 1 (0xB1) # # IMPORTANT NOTE: This is an original file from Ots Labs. If you wish to # make edits, it is recommended that you copy the contents of this file # to a new file first. Should you fail to do this, your changes may be # lost when Ots software updates are installed on your computer. If you # need to obtain the original version of this file at a later stage, # visit http://www.OtsAV.com # ######################################################################## # ******* Declare variables ******* # Arguments: variable name, initial value, maximum value !var[$deck_a_playing,0,1] # 1 = playing !var[$deck_b_playing,0,1] !var[$deck_a_jog_mode,0,1] # 0 = bending, 1 = scratching !var[$deck_b_jog_mode,0,1] !var[$deck_a_frame_search,0,1] # 1 = in frame search mode !var[$deck_b_frame_search,0,1] !var[$deck_a_search_spin_counter,0,7] # for dividing (by 6) jog !var[$deck_b_search_spin_counter,0,7] # pulses when frame searching !var[$deck_a_search_rate,0,2] # frame search speed via jog !var[$deck_b_search_rate,0,2] !var[$deck_a_scratch,0,1] # 1 = currently scratching !var[$deck_b_scratch,0,1] !var[$deck_a_bend,0,21] # non-zero = currently bending !var[$deck_b_bend,0,21] !var[$deck_a_bend_down,0,1] # 1 = bend down !var[$deck_b_bend_down,0,1] !var[$deck_a_bend_up,0,1] # 1 = bend up !var[$deck_b_bend_up,0,1] !var[$deck_a_scratch_state,0,2] # tracks jog wheel state for scratching !var[$deck_b_scratch_state,0,2] !var[$deck_a_bend_state,0,1] # tracks jog wheel state for bending !var[$deck_b_bend_state,0,1] !var[$deck_a_slider_index,0,1] # 0 = tempo, 1 = pitch !var[$deck_b_slider_index,0,1] !var[$deck_a_shift,0,1] # shift A button state !var[$deck_b_shift,0,1] # shift B button state !var[$global_shift,0,1] # global shift state # ******* Declare subroutines ******* !sub[@deck_a_try_bend] # this sub is used purely to gain !sub[@deck_b_try_bend] # use of another conditional !sub[@deck_a_try_scratch] !sub[@deck_b_try_scratch] !sub[@deck_a_try_scratch2] !sub[@deck_b_try_scratch2] !sub[@deck_a_jog_val_bend] # important to use sub for midi.velval-based !sub[@deck_b_jog_val_bend] # controls which call more than one command # in order to be efficient (CPU resources) !sub[@deck_a_jog_val_scratch] !sub[@deck_b_jog_val_scratch] !sub[@deck_a_cue_no_shift] !sub[@deck_b_cue_no_shift] !sub[@deck_a_slider_val] # new value from slider !sub[@deck_b_slider_val] !sub[@deck_a_slider_val_tempo] !sub[@deck_b_slider_val_tempo] !sub[@deck_a_slider_val_pitch] !sub[@deck_b_slider_val_pitch] !sub[@deck_a_playlist_loadnext] # load next item from playlist if !sub[@deck_b_playlist_loadnext] # deck is not currently playing # ******* Initialisation ******* # Called by OHM subsystem at startup. # Place any code here that is important to maintain state at launch sub[@_init] { # get current OtsAV state avStateRequest() # will generate appropriate Load, Play, etc events } # ******* Respond to OtsAV/other events ******* ######################################################## ####### Deck A: Load/Cue/Play-Pause/Frame Search/etc av[Play,A,E] { # Deck A Play (entered Playing state) VarSet($deck_a_playing,1) # save state for our own use } av[Play,A,D] { # Deck A Stop (left Playing state) VarSet($deck_a_playing,0) # clear state } av[FrameSearch,A,E] { # Deck A entered Frame Search mode VarSet($deck_a_frame_search,1) # save state for our own use VarSet($deck_a_search_spin_counter,3) } av[FrameSearch,A,D] { # Deck A left Frame Search mode VarSet($deck_a_frame_search,0) # clear state } ####### Deck B: Load/Cue/Play-Pause/Frame Search/etc av[Play,B,E] { # Deck B Play (entered Playing state) VarSet($deck_b_playing,1) # save state for our own use } av[Play,B,D] { # Deck B Stop (left Playing state) VarSet($deck_b_playing,0) # clear state } av[FrameSearch,B,E] { # Deck B entered Frame Search mode VarSet($deck_b_frame_search,1) # save state for our own use VarSet($deck_b_search_spin_counter,3) } av[FrameSearch,B,D] { # Deck B left Frame Search mode VarSet($deck_b_frame_search,0) # clear state } ######################################################## ####### Deck A: Primary transport controls midi.trigger[0xB1:0x08:0x7F] { # Deck A Play/Pause button down ($global_shift=0) avPlayPause(A,E) ($global_shift=1) avPlay(A) } midi.trigger[0xB1:0x08:0x00] { # Deck A Play/Pause button up avPlayPause(A,D) } midi.trigger[0xB1:0x09:0x7F] { # Deck A Cue button down ($global_shift=0) SubCall(@deck_a_cue_no_shift) ($global_shift=1) avCueSet(A) } sub[@deck_a_cue_no_shift] { # Deck A Cue button down without shift ($deck_a_scratch=0) avCue(A,E) ($deck_a_scratch=1) avCueSet(A) } midi.trigger[0xB1:0x09:0x00] { # Deck A Cue button up avCue(A,D) } midi.trigger[0xB1:0x0B:0x7F] { # Deck A Frame Search (back) button down avFrameSearch(A,-1) } midi.trigger[0xB1:0x0C:0x7F] { # Deck A Frame Search (forward) button down ($global_shift=0) avFrameSearch(A,+1) ($global_shift=1) Subcall(@deck_a_playlist_loadnext) # load next from playlist when shifted } midi.relval[0xB1:0x2D,0x40,0xC0,0x80] ($deck_a_frame_search=1) VarDec($deck_a_search_spin_counter) midi.relval[0xB1:0x2D,0x00,0xC0,0x00] ($deck_a_frame_search=1) VarInc($deck_a_search_spin_counter) var.set[$deck_a_search_spin_counter=0] { ($deck_a_search_rate=0) avFrameSearch(A,-1) ($deck_a_search_rate=1) avFrameSearch(A,-5) ($deck_a_search_rate=2) avFrameSearch(A,-20) VarInc($deck_a_search_rate) VarSet($deck_a_search_spin_counter,6) } var.set[$deck_a_search_spin_counter=7] { ($deck_a_search_rate=0) avFrameSearch(A,+1) ($deck_a_search_rate=1) avFrameSearch(A,+5) ($deck_a_search_rate=2) avFrameSearch(A,+20) VarInc($deck_a_search_rate) VarSet($deck_a_search_spin_counter,1) } timer.tick VarDec($deck_a_search_rate) ####### Deck B: Primary transport controls midi.trigger[0xB1:0x02:0x7F] { # Deck B Play/Pause button down ($global_shift=0) avPlayPause(B,E) ($global_shift=1) avPlay(B) } midi.trigger[0xB1:0x02:0x00] { # Deck B Play/Pause button up avPlayPause(B,D) } midi.trigger[0xB1:0x03:0x7F] { # Deck B Cue button down ($global_shift=0) SubCall(@deck_b_cue_no_shift) ($global_shift=1) avCueSet(B) } sub[@deck_b_cue_no_shift] { # Deck B Cue button down without shift ($deck_b_scratch=0) avCue(B,E) ($deck_b_scratch=1) avCueSet(B) } midi.trigger[0xB1:0x03:0x00] { # Deck B Cue button up avCue(B,D) } midi.trigger[0xB1:0x05:0x7F] { # Deck B Frame Search (back) button down avFrameSearch(B,-1) } midi.trigger[0xB1:0x06:0x7F] { # Deck B Frame Search (forward) button down ($global_shift=0) avFrameSearch(B,+1) ($global_shift=1) Subcall(@deck_b_playlist_loadnext) # load next from playlist when shifted } midi.relval[0xB1:0x2E,0x40,0xC0,0x80] ($deck_b_frame_search=1) VarDec($deck_b_search_spin_counter) midi.relval[0xB1:0x2E,0x00,0xC0,0x00] ($deck_b_frame_search=1) VarInc($deck_b_search_spin_counter) var.set[$deck_b_search_spin_counter=0] { ($deck_b_search_rate=0) avFrameSearch(B,-1) ($deck_b_search_rate=1) avFrameSearch(B,-5) ($deck_b_search_rate=2) avFrameSearch(B,-20) VarInc($deck_b_search_rate) VarSet($deck_b_search_spin_counter,6) } var.set[$deck_b_search_spin_counter=7] { ($deck_b_search_rate=0) avFrameSearch(B,+1) ($deck_b_search_rate=1) avFrameSearch(B,+5) ($deck_b_search_rate=2) avFrameSearch(B,+20) VarInc($deck_b_search_rate) VarSet($deck_b_search_spin_counter,1) } timer.tick VarDec($deck_b_search_rate) ######################################################## ####### Deck A: Jog mode/Bending/Scratching var.set[$deck_a_jog_mode=0] { # Bending mode ($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled } var.set[$deck_a_jog_mode=1] { # Scratching mode ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled } var.set[$deck_a_playing=0] { # Deck A Stop (left Playing state) ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled ($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled } var.set[$deck_a_frame_search=1] { # Deck A entered Frame Search mode ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled ($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled } sub[@deck_a_try_scratch] ($deck_a_playing=1) SubCall(@deck_a_try_scratch2) sub[@deck_a_try_scratch2] { ($deck_a_frame_search=0) VarSet($deck_a_scratch,1) } var.set[$deck_a_scratch=1] { # Enable Deck A scratching avScratch(A,E,0.0) } var.set[$deck_a_scratch=0] { # Disable Deck A scratching avScratch(A,D,0.0) } sub[@deck_a_try_bend] ($deck_a_frame_search=0) VarSet($deck_a_bend,1) var.set[$deck_a_bend=1] { # Enable Deck A jog bending and cancel Deck A bending buttons ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled avBend(A,E,0.0) } var.set[$deck_a_bend=0] { # Disable Deck A jog bending avBend(A,D,0.0) } var.set[$deck_a_shift=1] { # Enable Scratching jog mode VarSet($deck_a_jog_mode,1) } midi.velval[R,0xB1:0x2D,0x80,0x00,0,10.0,0.1,$deck_a_bend_state,0] ($deck_a_jog_mode=0) SubCall(@deck_a_jog_val_bend) midi.velval[R,0xB1:0x2D,0x80,0x00,0,15.0,0.3,$deck_a_scratch_state,1] ($deck_a_jog_mode=1) SubCall(@deck_a_jog_val_scratch) sub[@deck_a_jog_val_bend] { # new value from jog wheel ($deck_a_bend=1) avBendSet(A,_) } var.set[$deck_a_bend_state!=0] { # jog wheel active in bending mode ($deck_a_playing=1) SubCall(@deck_a_try_bend) } var.set[$deck_a_bend_state=0] { # jog wheel inactive in bending mode VarSet($deck_a_bend,0) # cancel bending } sub[@deck_a_jog_val_scratch] { # new value from jog wheel ($deck_a_scratch=1) avScratchSet(A,_) } var.set[$deck_a_scratch_state!=0] { # jog wheel active in scratching mode ($deck_a_shift=1) SubCall(@deck_a_try_scratch) } var.set[$deck_a_scratch_state!=1] { # jog wheel inactive in scratching mode ($deck_a_shift=0) VarSet($deck_a_jog_mode,0) # return to bending mode if shift has been already released } var.set[$deck_a_shift=0] { # Cancel Deck A scratching if shift button released and jog is inactive ($deck_a_scratch_state!=1) VarSet($deck_a_jog_mode,0) # return to bending mode } midi.trigger[0xB1:0x14:0x7F] ($deck_a_playing=1) VarSet($deck_a_bend_down,1) midi.trigger[0xB1:0x14:0x00] ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) midi.trigger[0xB1:0x13:0x7F] ($deck_a_playing=1) VarSet($deck_a_bend_up,1) midi.trigger[0xB1:0x13:0x00] ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) var.set[$deck_a_bend_down=1] { ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled avBend(A,E,-0.4) # bend down at 4% } var.set[$deck_a_bend_down=0] { avBend(A,D,0.0) # cancel bend down } var.set[$deck_a_bend_up=1] { ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled avBend(A,E,+0.4) # bend up at 4% } var.set[$deck_a_bend_up=0] { avBend(A,D,0.0) # cancel bend up } ####### Deck B: Jog mode/Bending/Scratching var.set[$deck_b_jog_mode=0] { # Bending mode ($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled } var.set[$deck_b_jog_mode=1] { # Scratching mode ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled } var.set[$deck_b_playing=0] { # Deck B Stop (left Playing state) ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled ($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled } var.set[$deck_b_frame_search=1] { # Deck B entered Frame Search mode ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled ($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled } sub[@deck_b_try_scratch] ($deck_b_playing=1) SubCall(@deck_b_try_scratch2) sub[@deck_b_try_scratch2] { ($deck_b_frame_search=0) VarSet($deck_b_scratch,1) } var.set[$deck_b_scratch=1] { # Enable Deck B scratching avScratch(B,E,0.0) } var.set[$deck_b_scratch=0] { # Disable Deck B scratching avScratch(B,D,0.0) } sub[@deck_b_try_bend] ($deck_b_frame_search=0) VarSet($deck_b_bend,1) var.set[$deck_b_bend=1] { # Enable Deck B jog bending and cancel Deck A bending buttons ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled avBend(B,E,0.0) } var.set[$deck_b_bend=0] { # Disable Deck B jog bending avBend(B,D,0.0) } var.set[$deck_b_shift=1] { # Enable Scratching jog mode VarSet($deck_b_jog_mode,1) } midi.velval[R,0xB1:0x2E,0x80,0x00,0,10.0,0.1,$deck_b_bend_state,0] ($deck_b_jog_mode=0) SubCall(@deck_b_jog_val_bend) midi.velval[R,0xB1:0x2E,0x80,0x00,0,15.0,0.3,$deck_b_scratch_state,1] ($deck_b_jog_mode=1) SubCall(@deck_b_jog_val_scratch) sub[@deck_b_jog_val_bend] { # new value from jog wheel ($deck_b_bend=1) avBendSet(B,_) } var.set[$deck_b_bend_state!=0] { # jog wheel active in bending mode ($deck_b_playing=1) SubCall(@deck_b_try_bend) } var.set[$deck_b_bend_state=0] { # jog wheel inactive in bending mode VarSet($deck_b_bend,0) # cancel bending } sub[@deck_b_jog_val_scratch] { # new value from jog wheel ($deck_b_scratch=1) avScratchSet(B,_) } var.set[$deck_b_scratch_state!=0] { # jog wheel active in scratching mode ($deck_b_shift=1) SubCall(@deck_b_try_scratch) } var.set[$deck_b_scratch_state!=1] { # jog wheel inactive in scratching mode ($deck_b_shift=0) VarSet($deck_b_jog_mode,0) # return to bending mode if shift has been already released } var.set[$deck_b_shift=0] { # Cancel Deck B scratching if shift button released and jog is inactive ($deck_b_scratch_state!=1) VarSet($deck_b_jog_mode,0) # return to bending mode } midi.trigger[0xB1:0x18:0x7F] ($deck_b_playing=1) VarSet($deck_b_bend_down,1) midi.trigger[0xB1:0x18:0x00] ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) midi.trigger[0xB1:0x17:0x7F] ($deck_b_playing=1) VarSet($deck_b_bend_up,1) midi.trigger[0xB1:0x17:0x00] ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) var.set[$deck_b_bend_down=1] { ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled avBend(B,E,-0.4) # bend down at 4% } var.set[$deck_b_bend_down=0] { avBend(B,D,0.0) # cancel bend down } var.set[$deck_b_bend_up=1] { ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled avBend(B,E,+0.4) # bend up at 4% } var.set[$deck_b_bend_up=0] { avBend(B,D,0.0) # cancel bend up } ######################################################## ####### Deck A: Bass/Mid/High EQ knobs midi.absval[S,0xB1:0x25,0x00,0x3F,0x7F] { # Deck A - Low EQ knob capture avEQGainBass(A,_) # Set Deck A Bass Level } midi.absval[S,0xB1:0x26,0x00,0x3F,0x7F] { # Deck A - Mid EQ knob capture avEQGainMid(A,_) # Set Deck A Mid Level } midi.absval[S,0xB1:0x27,0x00,0x3F,0x7F] { # Deck A - High EQ knob capture avEQGainHigh(A,_) # Set Deck A High Level } ####### Deck B: Bass/Mid/High EQ knobs midi.absval[S,0xB1:0x22,0x00,0x3F,0x7F] { # Deck B - Low EQ knob capture avEQGainBass(B,_) # Set Deck B Bass Level } midi.absval[S,0xB1:0x23,0x00,0x3F,0x7F] { # Deck B - Mid EQ knob capture avEQGainMid(B,_) # Set Deck B Mid Level } midi.absval[S,0xB1:0x24,0x00,0x3F,0x7F] { # Deck B - High EQ knob capture avEQGainHigh(B,_) # Set Deck B High Level } ######################################################## ####### Deck A: Bass/Mid/High cut midi.trigger[0xB1:0x0D:0x7F] { # Deck A - Cut Low button down avEQCutBass(A,T) # Toggle Deck A Bass Cut } midi.trigger[0xB1:0x0E:0x7F] { # Deck A - Cut Mid button down avEQCutMid(A,T) # Toggle Deck A Mid Cut } midi.trigger[0xB1:0x0F:0x7F] { # Deck A - Cut High button down avEQCutHigh(A,T) # Toggle Deck A High Cut } ####### Deck B: Bass/Mid/High cut midi.trigger[0xB1:0x12:0x7F] { # Deck B - Cut Low button down avEQCutBass(B,T) # Toggle Deck B Bass Cut } midi.trigger[0xB1:0x11:0x7F] { # Deck B - Cut Mid button down avEQCutMid(B,T) # Toggle Deck B Mid Cut } midi.trigger[0xB1:0x10:0x7F] { # Deck B - Cut High button down avEQCutHigh(B,T) # Toggle Deck B High Cut } ######################################################## ####### Crossfader midi.absval[S,0xB1:0x28,0x00,0x3F,0x7F] { ($global_shift=0) avXFaderSet(_) # normal sync logic } midi.trigger[0xB1:0x28:0x00,0xFF:0xFF:0xE0] { # d2 between 0x00 and 0x1F ($global_shift=1) avXFaderSet(-1.0,F0) # force full Deck A slider position } midi.trigger[0xB1:0x28:0x60,0xFF:0xFF:0xE0] { # d2 between 0x60 and 0x7F ($global_shift=1) avXFaderSet(1.0,F0) # force full Deck B slider position } ######################################################## ####### Deck A: Shift key midi.trigger[0xB1:0x1B:0x7F] VarSet($deck_a_shift,1) midi.trigger[0xB1:0x1B:0x00] VarSet($deck_a_shift,0) ####### Deck B: Shift key midi.trigger[0xB1:0x1C:0x7F] VarSet($deck_b_shift,1) midi.trigger[0xB1:0x1C:0x00] VarSet($deck_b_shift,0) ####### Global Shift state var.set[$deck_a_shift=1] VarSet($global_shift,1) var.set[$deck_a_shift=0] ($deck_b_shift=0) VarSet($global_shift,0) var.set[$deck_b_shift=1] VarSet($global_shift,1) var.set[$deck_b_shift=0] ($deck_a_shift=0) VarSet($global_shift,0) ####### Deck A + B Shift - Mix Now var.set[$deck_a_shift=1] { ($deck_b_shift=1) avNext() # Mix now } var.set[$deck_b_shift=1] { ($deck_a_shift=1) avNext() # Mix now } ######################################################## ####### Cue A and Cue B button functionality midi.trigger[0xB1:0x15:0x7F] { avMixer.Cue(A,T) # Toggle Deck A Mixer Cue Button } midi.trigger[0xB1:0x19:0x7F] { avMixer.Cue(B,T) # Toggle Deck B Mixer Cue Button } ######################################################## ####### Sync A and Sync B button functionality midi.trigger[0xB1:0x0A:0x7F] { # Sync A button down ($deck_a_slider_index=0) avBPMMatch.Tempo(A) ($deck_a_slider_index=1) avBPMMatch.Pitch(A) } midi.trigger[0xB1:0x04:0x7F] { # Sync B button down ($deck_b_slider_index=0) avBPMMatch.Tempo(B) ($deck_b_slider_index=1) avBPMMatch.Pitch(B) } ######################################################## ####### Mixer Volume Knobs ####### Deck A midi.relval[0xB1:0x2B,0x40,0xC0,0x80] avLevelSet(A,-1.0,F8) # Decrements Deck A level on OtsAV Mixer (using F8 flag) midi.relval[0xB1:0x2B,0x00,0xC0,0x00] avLevelSet(A,+1.0,F8) # Increments Deck A level on OtsAV Mixer (using F8 flag) midi.relval[0xB1:0x2B,0x40,0xC0,0x80] ($global_shift=1) avLevelSet(A,-1.0,F0) # bypass sync logic and snap value to bottom level midi.relval[0xB1:0x2B,0x00,0xC0,0x00] ($global_shift=1) avLevelSet(A,0.0,F0) # bypass sync logic and snap value to centre ####### Deck B midi.relval[0xB1:0x2C,0x40,0xC0,0x80] avLevelSet(B,-1.0,F8) # Decrements Deck B level on OtsAV Mixer (using F8 flag) midi.relval[0xB1:0x2C,0x00,0xC0,0x00] avLevelSet(B,+1.0,F8) # Increments Deck B level on OtsAV Mixer (using F8 flag) midi.relval[0xB1:0x2C,0x40,0xC0,0x80] ($global_shift=1) avLevelSet(B,-1.0,F0) # bypass sync logic and snap value to bottom level midi.relval[0xB1:0x2C,0x00,0xC0,0x00] ($global_shift=1) avLevelSet(B,0.0,F0) # bypass sync logic and snap value to centre ######################################################## ####### Tempo/Pitch Slider mode (tempo or pitch) midi.trigger[0xB1:0x16:0x7F] { # slider mode A button down VarIncWrap($deck_a_slider_index) } midi.trigger[0xB1:0x1A:0x7F] { # slider mode B button down VarIncWrap($deck_b_slider_index) } ######################################################## ####### Deck A: Slider midi.absval[S,0xB1:0x29,0x7F,0x3F,0x00] SubCall(@deck_a_slider_val) sub[@deck_a_slider_val] { # new value from slider ($deck_a_slider_index=0) SubCall(@deck_a_slider_val_tempo) ($deck_a_slider_index=1) SubCall(@deck_a_slider_val_pitch) } sub[@deck_a_slider_val_tempo] { # slider pos -- tempo ($global_shift=0) avTempoSet(A,_) # normal sync logic ($global_shift=1) avTempoSet(A,_,F1) # force synced state } sub[@deck_a_slider_val_pitch] { # slider pos -- pitch ($global_shift=0) avPitchSet(A,_) # normal sync logic ($global_shift=1) avPitchSet(A,_,F1) # force synced state } var.set[$deck_a_slider_index=0] { avTempoSet(A,0.0,F2|F7) # init sync with last pitch slider position } var.set[$deck_a_slider_index=1] { avPitchSet(A,0.0,F2|F6) # init sync with last tempo slider position } midi.trigger[0xB1:0x07:0x7F] { # Cycle Range ($deck_a_slider_index=0) avSliderRangeSet.Tempo(A,0) ($deck_a_slider_index=1) avSliderRangeSet.Pitch(A,0) } av[SliderRangeNew.Tempo,A] { ($deck_a_slider_index=0) avTempoSet(A,0.0,F2|F6) # init sync with last tempo slider position } av[SliderRangeNew.Pitch,A] { ($deck_a_slider_index=1) avPitchSet(A,0.0,F2|F7) # init sync with last pitch slider position } ####### Deck B: Slider midi.absval[S,0xB1:0x2A,0x7F,0x3F,0x00] SubCall(@deck_b_slider_val) sub[@deck_b_slider_val] { # new value from slider ($deck_b_slider_index=0) SubCall(@deck_b_slider_val_tempo) ($deck_b_slider_index=1) SubCall(@deck_b_slider_val_pitch) } sub[@deck_b_slider_val_tempo] { # slider pos -- tempo ($global_shift=0) avTempoSet(B,_) # normal sync logic ($global_shift=1) avTempoSet(B,_,F1) # force synced state } sub[@deck_b_slider_val_pitch] { # slider pos -- pitch ($global_shift=0) avPitchSet(B,_) # normal sync logic ($global_shift=1) avPitchSet(B,_,F1) # force synced state } var.set[$deck_b_slider_index=0] { avTempoSet(B,0.0,F2|F7) # init sync with last pitch slider position } var.set[$deck_b_slider_index=1] { avPitchSet(B,0.0,F2|F6) # init sync with last tempo slider position } midi.trigger[0xB1:0x01:0x7F] { # Cycle Range ($deck_b_slider_index=0) avSliderRangeSet.Tempo(B,0) ($deck_b_slider_index=1) avSliderRangeSet.Pitch(B,0) } av[SliderRangeNew.Tempo,B] { ($deck_b_slider_index=0) avTempoSet(B,0.0,F2|F6) # init sync with last tempo slider position } av[SliderRangeNew.Pitch,B] { ($deck_b_slider_index=1) avPitchSet(B,0.0,F2|F7) # init sync with last pitch slider position } ######################################################## ####### Load Next Track sub[@deck_a_playlist_loadnext] { # load next item from playlist ($deck_a_playing=0) avLoadNext(A,F1) # but only if deck not playing } sub[@deck_b_playlist_loadnext] { # load next item from playlist ($deck_b_playing=0) avLoadNext(B,F1) # but only if deck not playing }